<!--
 * @Author: chenhaoran
 * @Date: 2024-08-15 14:56:41
 * @LastEditors: chenhaoran
 * @LastEditTime: 2024-08-15 15:10:26
-->
<template>
  <div class="my-table" ref="tableWrap">
    <el-table
      ref="zhyyTable"
      border
      style="width: 100%"
      :data="viewData"
      :row-key="rowKey"
      :stripe="stripe"
      :height="height ? height : '100%'"
      @selection-change="handleSelectionChange"
      :header-cell-style="headerCellStyle"
      :row-style="rowStyle"
      :highlight-current-row="singleSelect"
      @current-change="handleCurrentChange"
    >
      <!-- 单选 -->
      <el-table-column v-if="singleSelect && !selection" align="center" width="55">
        <template slot-scope="scope">
          <!-- 空标签不显示内容 -->
          <el-radio class="single-radio" v-model="currentRow" :label="scope.row">{{``}}</el-radio>
        </template>
      </el-table-column>
      <!-- 多选 -->
      <el-table-column
        v-if="selection && !singleSelect"
        align="center"
        width="55"
        type="selection"
      />
      <!-- 序号列 -->
      <el-table-column
        type="index"
        v-if="showIndex"
        :label="configFlag.indexName || '序号'"
        :width="configFlag.indexWidth || 50"
        align="center"
      >
        <template slot-scope="scope">
          <!-- 每页都是从 1 开始 -->
          {{ scope.$index + 1 }}
          <!-- 第二页从 11 开始 -->
          <!-- {{ (pageValue.pageNum - 1) * 10 + (scope.$index + 1) }} -->
        </template>
      </el-table-column>

      <!-- 循环遍历表头展示数据 -->
      <!-- 加了fixed属性，需要给列添加width，否则可能会没有横向滚动条导致错位 -->
      <el-table-column
        v-for="item in viewColumns"
        :key="item.fieldName"
        :width="item.width || ''"
        :prop="item.fieldName"
        :label="item.label"
        :align="item.align || 'center'"
        :sortable="item.sortable"
        :fixed="item.fixed || false"
        header-align="center"
        :show-overflow-tooltip="item.showOverFlowTooltip"
      >
        <template slot="header" slot-scope="{ column }">
          {{ column.label }}
          <el-tooltip
            class="item"
            effect="dark"
            v-if="item.headertip"
            :content="item.headertip"
            placement="top-start"
          >
            <i class="el-icon-warning"></i>
          </el-tooltip>
        </template>
        <template slot-scope="scope">
          <!-- 枚举值 -->
          <div
            v-if="item.type == 'statMap'"
          >{{ statMaps(item.options)[scope.row[item.fieldName]] || '--' }}</div>
          <!-- 需提示过长信息 -->
          <div v-else-if="item.showOverFlowTooltip">
            <div class="show-tooltip">{{ scope.row[item.fieldName] || '--' }}</div>
          </div>
          <!-- 字段link事件 -->
          <div v-else-if="item.rowLink">
            <div class="row-link">
              <el-link
                type="primary"
                @click="
  handleRowLinkClick(scope.$index, scope.column, scope.row)
  "
              >{{ scope.row[item.fieldName] }}</el-link>
              <!-- {{ scope.row[item.fieldName] || '--' }} -->
            </div>
          </div>
          <!-- 保留两位小数 -->
          <div v-else-if="item.type == 'tofix2'">
            {{
            scope.row[item.fieldName]
            ? Number(scope.row[item.fieldName]).toFixed(2)
            : '--'
            }}
          </div>
          <!-- 金额千分位展示 -->
          <div v-else-if="item.type == 'money'">
            <span>{{ getMoneyK(scope.row[item.fieldName]) || '--' }}</span>
          </div>
          <!-- el-tag标签 -->
          <div v-else-if="item.type == 'tag'">
            <!-- 动态展示标签type -->
            <el-tag
              v-if="item.attr && item.attr.dynamicType"
              v-bind="item.attr"
              :type="getDynamicType(scope.row, item.attr.dynamicType)"
            >
              <div
                v-if="item.options && item.options.length"
              >{{ statMaps(item.options)[scope.row[item.fieldName]] || '--' }}</div>
              <div v-else>{{ scope.row[item.fieldName] || '--' }}</div>
            </el-tag>
            <!-- 绑定多个普通属性 -->
            <el-tag v-else-if="item.attr" v-bind="item.attr">{{ scope.row[item.fieldName] }}</el-tag>

            <!-- 最普通标签，默认属性 -->
            <el-tag v-else>{{ scope.row[item.fieldName] }}</el-tag>
          </div>
          <div v-else-if="item.dateFormat">
            {{ scope.row[item.fieldName] ? $moment(scope.row[item.fieldName]).format(item.dateFormat)
            : '--'
            }}
          </div>
          <!-- 根据需求添加效果 返回的slot可以优化.自己来吧.可以实现操作列等 -->
          <slot
            v-else-if="item.type == undefined && item.slotname"
            :scope="scope"
            :name="item.slotname"
          />
          <!-- 最普通的情况 -->
          <div v-else>
            <span>{{ scope.row[item.fieldName] || '--' }}</span>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      v-if="isNeedPage"
      :total="pageValue.total"
      :page-count="pageValue.pageNum"
      :page-size="pageValue.pageSize"
      :page-sizes="pageSizes"
      :current-page.sync="pageValue.pageNum"
      layout="total, sizes, prev, pager, next, jumper"
      class="fr"
      style="margin-top: 12px"
      @size-change="sizeChange"
      @current-change="currentChange"
      @prev-click="prevClick"
      @next-click="nextClick"
    />
  </div>
</template>

<script>
export default {
  name: 'my-table',
  props: {
    // 多选保存选中数据
    rowKey: {
      default: () => (row) => row.index,
    },
    // 是否需要序号
    showIndex: {
      type: Boolean,
      default: () => true,
    },
    // 是否为单选
    singleSelect: {
      type: Boolean,
      default: () => false,
    },
    // 是否需要多选
    selection: {
      type: Boolean,
      default: () => false,
    },
    // 为表头设计样式
    headerCellStyle: {
      default: () => {
        return {
          background: 'rgb(243, 246, 255)',
          height: '40px',
          color: '#2e45db',
        }
      },
    },
    // 为每一行设计样式，比如设置每行的高度等等
    rowStyle: {
      default: () => {
        return { height: '50px' }
      },
    },
    columns: {
      // 表头数据 文案和绑定值，以及需要特殊处理的slot
      type: Array,
      default: () => [],
    },
    data: {
      type: Array, // 后台数据
    },
    // 是否需要分页
    isNeedPage: {
      type: Boolean,
      default: () => false,
    },
    // 分页数据查询器
    pageAjax: Function,
    // 分页参数
    pageValue: {
      // 分页数据
      type: Object,
      default: () => {
        return {
          pageNum: 1,
          pageSize: 10,
          total: 0,
          currentPage: 1, //当前页
        }
      },
    },
    // 每页多少条的选项
    pageSizes: {
      type: Array,
      default: () => {
        return [10, 20, 50, 100]
      },
    },
    // 表格配置项
    configFlag: {
      // 配置 其他table配置依次添加
      type: Object,
      default: () => {
        return {
          indexWidth: 70, //序号列宽
          btn: false, //序号添加自定义html
          // 这里不全面，可根据实际情况添加
        }
      },
    },
    height: {
      // 可以监听屏幕高度获取。
      // 高度
      type: Number
    },
    stripe: {
      type: Boolean,
      default: () => false
    }
  },
  data() {
    return {
      records: [], // 当前页面数据
      currentRow: null
    }
  },
  created() { },
  mounted() {
    this.doAjax()
  },
  computed: {
    // 页面展示数据
    viewData() {
      if (this.isNeedPage && this.data) { // 一般情况下都是互斥，prop传了data一般为不分页
        let data = this.data,
          start = (this.pageValue.pageNum - 1) * this.pageValue.pageSize,
          end = this.pageValue.pageNum * this.pageValue.pageSize,
          max = data.length,
          records = []
        for (let i = start; i < max && i < end; i++) {
          records.push(data[i])
        }
        return records
      } else {
        return this.data ? this.data : this.records
      }
    },
    // 真实展示列数据
    viewColumns() {
      return this.columns.filter((col) => !col.hidden)
    },
  },
  methods: {
    refresh() {
      this.pageValue.pageNum = 1
      this.pageValue.pageSize = 10
      this.doAjax()
    },
    // 分页数据查询器
    doAjax() {
      if (this.isNeedPage && typeof this.pageAjax == 'function') {
        this.pageAjax(
          {
            pageNum: this.pageValue.pageNum,
            pageSize: this.pageValue.pageSize,
          },
          ({ records, recordsTotal }) => {
            // 处理翻页时默认高亮第一条数据的问题
            if (this.singleSelect) this.$refs.zhyyTable.setCurrentRow()
            this.records = records || []
            this.pageValue.total = recordsTotal
          }
        )
      }
    },
    // 用于表格中字段是枚举值的列 比如性别 0 代表女 1代表男，就不需要对后台数据单独处理了
    /**
    ```
    tableconfig：
    {
    label:‘多选’,
    fieldName:'selections',
    type:'statMap',
    options:[{value:'1',label:'男'},{value:'0',label:'女'}]
    }
    ```
    */
    statMaps(list) {
      if (!list) return
      let obj = {}
      list.forEach((item) => {
        obj[item.value || item.id] = item.label || item.value
      })
      return obj
    },
    // 金额千位展示：1,234,567,890
    getMoneyK(money) {
      if (typeof money === 'number') {
        money = money.toString()
      }
      var pattern = /(-?\d+)(\d{3})/
      while (pattern.test(money)) {
        money = money.replace(pattern, '$1,$2')
      }
      return money
    },
    // 清空选中
    clearSelected() {
      // 父组件通过ref调用clearSelected方法，例如 this.$refs.clearTable.clearSelected()
      this.$refs.zhyyTable.clearSelection()
    },
    /*
    默认选中
    需要默认选中的在组件中通过this.$refs.zhyyTable.selected(默认选中的数据:Array)
    */
    selected(data) {
      if (data.length > 0) {
        data.forEach((item) => {
          this.$refs.zhyyTable.toggleRowSelection(item, true)
        })
      }
    },
    // 设置条数
    sizeChange(size) {
      this.pageValue.pageSize = size
      this.pageValue.pageNum = 1
      this.doAjax()
    },
    // 翻页，直接跳转
    currentChange(page) {
      this.pageValue.pageNum = page
      this.doAjax()
    },
    //上一页
    prevClick(val) {
      this.$emit('prevClick', val)
    },
    //下一页
    nextClick(val) {
      this.$emit('nextClick', val)
    },
    // 单选
    handleCurrentChange(currentRow, oldCurrentRow) {
      this.currentRow = currentRow
      this.$emit('handleCurrentChange', currentRow)
    },
    // 多选
    handleSelectionChange(val) {
      this.$emit('handleSelectionChange', val)
    },
    // 多选
    handleSelection(val, row) {
      this.$emit('handleSelection', { val, row })
    },
    handleCellEnter(row, column, cell, event) {
      this.$emit('handleCellEnter', { row, column, cell, event })
    },
    //编辑
    handleEdit(index, row, colIndex, field) {
      this.$emit('handleEdit', { index, row, colIndex, field })
    },
    //下拉框事件
    onSelected(index, row, field) {
      this.$emit('onSelected', { index, row, field })
    },
    //按钮点击事件
    onClickBtn(index, row) {
      this.$emit('onClickBtn', { index, row })
    },
    // 行点击事件
    handleRowLinkClick(index, column, row) {
      let data = {
        index: index,
        row: row,
        column: column,
      }
      this.$emit('rowLink', data)
    },
    /**
    * 可根据行数据状态动态渲染不同类型标签
    * attr: {
    type: 'info',
    dynamicType: {
    func: (row) => {
    return row.state == '1' ? 'success' : 'warning'
    }
    },
    hit: true,
    size: 'small',
    },
    */
    getDynamicType(row, dynamicTypeObj) {
      if (typeof dynamicTypeObj.func === 'function') {
        return dynamicTypeObj.func(row)
      }
    },
  },
}
</script>
<style lang="scss" scoped>
.my-table {
  /* height: 100%;
display: flex;
flex-direction: column;
// flex: 1;
// overflow-x: hidden; */
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-content: space-between;
  box-sizing: border-box;
  overflow: hidden;
  .show-tooltip {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    cursor: default;
  }
  ::v-deep .el-pagination__editor.el-input {
    width: 80px;
  }
  .el-pager li {
    background: transparent;
  }
  .el-pagination {
    .btn-prev,
    .btn-next {
      background-color: transparent;
    }
  }
  .fr {
    height: 43px;
  }
}
::v-deep .single-radio .el-radio__label {
  display: none;
}
</style>
